/**
 * 
 */
package optimization.naturalOptimization.population.individual.pso;

import optimization.naturalOptimization.population.Population;
import optimization.naturalOptimization.population.individual.Individual;

/**
 * This class provides a particle for the pso algorithm.
 * 
 * @author Kevin Wagner
 * @version 1.0
 * @param <T>
 *            Search Space type
 * 
 */
public abstract class Particle<T> extends Individual<T> {

	/**
	 * Creates a new particle for the given population.
	 * 
	 * @param parentPopulation
	 */
	public Particle(Population parentPopulation) {
		super(parentPopulation);
	}

	private T velocity;
	private T personalBest;
	private double personalBestFitness;
	private T neighborhoodBest;
	private double neighborhoodBestFitness;

	/**
	 * Returns the velocity of the particle.
	 * 
	 * @return the velocity
	 */
	public T getVelocity() {
		return velocity;
	}

	/**
	 * Sets the velocity of the particle.
	 * 
	 * @param velocity
	 *            new velocity
	 */
	public void setVelocity(T velocity) {
		this.velocity = velocity;
	}

	/**
	 * Returns the personal best position of the particle.
	 * 
	 * @return the personal best position
	 */
	public T getPersonalBest() {
		return personalBest;
	}

	/**
	 * Sets the personal best position of the particle.
	 * 
	 * @param personalBest
	 *            new personal best position
	 */
	public void setPersonalBest(T personalBest) {
		this.personalBest = personalBest;
	}

	/**
	 * Returns the best position in the neighborhood of the particle.
	 * 
	 * @return the neighborhoods best position
	 */
	public T getNeighborhoodBest() {
		return neighborhoodBest;
	}

	/**
	 * Sets the best position in the neighborhood of the particle.
	 * 
	 * @param neighborhoodBest
	 *            new neighborhoods best position
	 */
	public void setNeighborhoodBest(T neighborhoodBest) {
		this.neighborhoodBest = neighborhoodBest;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see optimization.naturalOptimization.population.Individual#performStep()
	 */
	public void performStep() {
		velocityUpdate();
		positionUpdate();
	}

	/**
	 * Updates the position of the particle.
	 */
	protected abstract void positionUpdate();

	/**
	 * Updates the velocity of the particle.
	 */
	protected abstract void velocityUpdate();

	/**
	 * Returns the fitness value of the personal best position.
	 * 
	 * @return fitness value of pbest
	 */
	public double getPersonalBestFitness() {
		return personalBestFitness;
	}

	/**
	 * Sets the fitness value of the personal best position.
	 * 
	 * @param personalBestFitness
	 *            new fitness value of pbest
	 */
	public void setPersonalBestFitness(double personalBestFitness) {
		this.personalBestFitness = personalBestFitness;
	}

	/**
	 * Returns the fitness value of the neighborhood best position.
	 * 
	 * @return fitness value of nbest
	 */
	public double getNeighborhoodBestFitness() {
		return neighborhoodBestFitness;
	}

	/**
	 * Sets the fitness value of the neighborhood best position.
	 * 
	 * @param neighborhoodBestFitness
	 *            new fitness value of nbest
	 */
	public void setNeighborhoodBestFitness(double neighborhoodBestFitness) {
		this.neighborhoodBestFitness = neighborhoodBestFitness;
	}

}
